//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Documents;
using OpenLS.Core.Serialization;
using OpenLS.Drawing.Serialization;

namespace OpenLS.Drawing
{
    /// <summary>
    /// Represents a body of text. This is similar to a small flow document.
    /// </summary>
    public class TextBody : IOfficeXmlSerializableAs
    {
        private TextBodyProperties bodyPr;
        private TextListStyle lstStyle;
        private List<TextParagraph> paragraphs = new List<TextParagraph>();

        public TextBody()
        {
        }

        public TextBody(string text)
        {
            Paragraphs.Add(new TextParagraph(text));
        }

        public TextListStyle ListStyle
        {
            get
            {
                if (lstStyle == null)
                    lstStyle = new TextListStyle();
                return lstStyle;
            }
            set { lstStyle = value; }
        }


        public TextBodyProperties BodyProperties
        {
            get
            {
                if (bodyPr == null)
                    bodyPr = new TextBodyProperties();
                return bodyPr;
            }
            set { bodyPr = value; }
        }


        public List<TextParagraph> Paragraphs
        {
            get { return paragraphs; }
        }

        public VerticalAlignment VerticalAlignment
        {
            get
            {
                if (BodyProperties == null)
                    return VerticalAlignment.Center;
                switch (BodyProperties.Anchor)
                {
                    case TextAnchoringType.Top:
                        return VerticalAlignment.Top;
                    case TextAnchoringType.Center:
                        return VerticalAlignment.Center;
                    case TextAnchoringType.Bottom:
                        return VerticalAlignment.Bottom;
                    case TextAnchoringType.Distributed:
                    case TextAnchoringType.Justified:
                        return VerticalAlignment.Stretch;
                    default:
                        throw new NotSupportedException();
                }
            }
        }

        public  FlowDocument Document
        {
            get
            {
                FlowDocument result = new FlowDocument();
                result.TextAlignment = TextAlignment.Center;
                foreach (TextParagraph p in Paragraphs)
                {
                    result.Blocks.Add(p.Paragraph);
                }
                if (BodyProperties != null)
                {
                    foreach (Setter setter in BodyProperties.GetAllSetters())
                    {
                        result.SetValue(setter.Property, setter.Value);
                    }
                }
                result.Background = null;
                return result;
            }
            internal set
            {
                Contract.Requires(value != null);
                this.Paragraphs.Clear();
                foreach (Paragraph p in value.Blocks)
                {
                    this.Paragraphs.Add(TextParagraph.FromParagraph (p));
                }

            }
        }

        #region IOfficeXmlSerializableAs Members

        void IOfficeXmlSerializableAs.ReadXmlAs(string name, ReadContext context)
        {
            using (var c = context.ReadAndSwitch(name, DrawingConstants.DrawingNamespaceUri, false))
            {
                BodyProperties = c.ReadElement<TextBodyProperties>();
                ReadContext cc = c.SwitchNamespace(DrawingConstants.DrawingNamespaceUri, false);
                ListStyle = cc.ReadOptionalElementAs<TextListStyle>("lstStyle");
                paragraphs = c.ReadOptionalWhile<TextParagraph>("p");
            }
        }

        void IOfficeXmlSerializableAs.WriteXmlAs(string name, WriteContext context)
        {
            using (WriteContext c = context.WriteAndSwitch(name, DrawingConstants.DrawingNamespace))
            {
                c.WriteElement(BodyProperties);
                WriteContext drawingContext = new WriteContext(DrawingConstants.DrawingNamespace, c.Writer, c.Part);
                drawingContext.WriteOptionalElementAs(ListStyle, "lstStyle");
                if (paragraphs != null)
                    foreach (IOfficeXmlSerializable item in paragraphs)
                        item.WriteXml(c);
            }
        }

        #endregion
    }
}